package cn.edu.tju.wallet.service;

import cn.edu.tju.core.model.User;
import cn.edu.tju.wallet.domain.VipLevel;
import cn.edu.tju.wallet.dto.VipLevelDTO;
import cn.edu.tju.wallet.repository.VipLevelRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * VIP等级服务层
 */
@Service
public class VipLevelService {

    @Autowired
    private VipLevelRepository vipLevelRepository;

    /**
     * 创建VIP等级
     */
    @Transactional
    public VipLevelDTO createVipLevel(VipLevelDTO dto) {
        // 检查等级名称是否已存在
        Optional<VipLevel> existingByName = vipLevelRepository.findByName(dto.getName());
        if (existingByName.isPresent()) {
            throw new IllegalArgumentException("VIP等级名称已存在");
        }

        // 检查等级数值是否已存在
        if (vipLevelRepository.existsByLevel(dto.getLevel())) {
            throw new IllegalArgumentException("VIP等级数值已存在");
        }

        VipLevel vipLevel = new VipLevel();
        vipLevel.setName(dto.getName());
        vipLevel.setLevel(dto.getLevel());
        vipLevel.setMinTotalConsumption(dto.getMinTotalConsumption());
        vipLevel.setMinTotalRecharge(dto.getMinTotalRecharge());
        vipLevel.setOverdraftMultiplier(dto.getOverdraftMultiplier() != null ?
                dto.getOverdraftMultiplier() : BigDecimal.ONE);
        vipLevel.setInterestDiscount(dto.getInterestDiscount() != null ?
                dto.getInterestDiscount() : BigDecimal.ONE);
        vipLevel.setStatus(VipLevel.RuleStatus.ACTIVE);
        vipLevel.setPriority(dto.getPriority() != null ? dto.getPriority() : dto.getLevel());

        // 验证参数
        vipLevel.validate();

        VipLevel saved = vipLevelRepository.save(vipLevel);
        return convertToDTO(saved);
    }

    /**
     * 更新VIP等级
     */
    @Transactional
    public VipLevelDTO updateVipLevel(Long id, VipLevelDTO dto) {
        VipLevel vipLevel = vipLevelRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("VIP等级不存在"));

        // 检查等级名称是否已被其他记录使用
        Optional<VipLevel> existingByName = vipLevelRepository.findByName(dto.getName());
        if (existingByName.isPresent() && !existingByName.get().getId().equals(id)) {
            throw new IllegalArgumentException("VIP等级名称已被其他记录使用");
        }

        // 检查等级数值是否已被其他记录使用
        if (!vipLevel.getLevel().equals(dto.getLevel()) && vipLevelRepository.existsByLevel(dto.getLevel())) {
            throw new IllegalArgumentException("VIP等级数值已被其他记录使用");
        }

        vipLevel.setName(dto.getName());
        vipLevel.setLevel(dto.getLevel());
        vipLevel.setMinTotalConsumption(dto.getMinTotalConsumption());
        vipLevel.setMinTotalRecharge(dto.getMinTotalRecharge());
        vipLevel.setOverdraftMultiplier(dto.getOverdraftMultiplier());
        vipLevel.setInterestDiscount(dto.getInterestDiscount());
        vipLevel.setPriority(dto.getPriority() != null ? dto.getPriority() : dto.getLevel());

        // 验证参数
        vipLevel.validate();

        VipLevel saved = vipLevelRepository.save(vipLevel);
        return convertToDTO(saved);
    }

    /**
     * 删除VIP等级
     */
    @Transactional
    public void deleteVipLevel(Long id) {
        VipLevel vipLevel = vipLevelRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("VIP等级不存在"));

        // 检查是否有用户使用该等级
        // 这里可以添加业务逻辑检查

        vipLevelRepository.delete(vipLevel);
    }

    /**
     * 获取所有VIP等级
     */
    public List<VipLevelDTO> getAllVipLevels() {
        List<VipLevel> vipLevels = vipLevelRepository.findAllByOrderByLevelAsc();
        return vipLevels.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 根据ID获取VIP等级
     */
    public VipLevelDTO getVipLevelById(Long id) {
        VipLevel vipLevel = vipLevelRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("VIP等级不存在"));
        return convertToDTO(vipLevel);
    }

    /**
     * 根据等级数值获取VIP等级
     */
    public Optional<VipLevelDTO> getVipLevelByLevel(Integer level) {
        Optional<VipLevel> vipLevel = vipLevelRepository.findByLevel(level);
        return vipLevel.map(this::convertToDTO);
    }

    /**
     * 获取所有激活的VIP等级
     */
    public List<VipLevelDTO> getAllActiveVipLevels() {
        List<VipLevel> vipLevels = vipLevelRepository.findAllActiveOrderByPriority(VipLevel.RuleStatus.ACTIVE);
        return vipLevels.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 为用户评估VIP等级
     * 根据用户的累计消费和充值金额，自动评估适合的VIP等级
     */
    public VipLevelDTO evaluateUserVipLevel(User user) {
        if (user == null) {
            return null;
        }

        BigDecimal totalConsumption = user.getTotalConsumption() != null ?
                user.getTotalConsumption() : BigDecimal.ZERO;
        BigDecimal totalRecharge = user.getTotalRecharge() != null ?
                user.getTotalRecharge() : BigDecimal.ZERO;

        // 获取所有激活的VIP等级，按优先级排序
        List<VipLevel> activeLevels = vipLevelRepository.findAllActiveOrderByPriority(VipLevel.RuleStatus.ACTIVE);

        // 遍历找到第一个符合条件的等级
        for (VipLevel level : activeLevels) {
            if (level.isApplicable(totalConsumption, totalRecharge)) {
                return convertToDTO(level);
            }
        }

        // 没有符合的等级，返回默认（普通用户）
        return null;
    }

    /**
     * 为用户升级VIP等级
     */
    @Transactional
    public VipLevelDTO upgradeUserVipLevel(User user) {
        VipLevelDTO newLevel = evaluateUserVipLevel(user);
        if (newLevel == null) {
            // 普通用户，无VIP等级
            user.setVipLevel("普通用户", 0);
            return null;
        }

        // 如果新等级高于当前等级，则升级
        Integer currentLevel = user.getVipLevelValue();
        if (newLevel.getLevel() > currentLevel) {
            user.setVipLevel(newLevel.getName(), newLevel.getLevel());
            return newLevel;
        }

        // 不需要升级
        return getVipLevelByLevel(currentLevel).orElse(null);
    }

    /**
     * 获取用户的当前VIP等级DTO
     */
    public VipLevelDTO getUserCurrentVipLevel(User user) {
        if (user == null || user.getVipLevelValue() == null || user.getVipLevelValue() == 0) {
            return null;
        }
        return getVipLevelByLevel(user.getVipLevelValue()).orElse(null);
    }

    /**
     * 初始化默认VIP等级
     * 在系统首次启动时调用
     */
    @Transactional
    public void initDefaultVipLevels() {
        // 检查是否已有VIP等级数据
        List<VipLevel> existingLevels = vipLevelRepository.findAll();
        if (!existingLevels.isEmpty()) {
            return; // 已有数据，不需要初始化
        }

        // 创建默认的5个VIP等级
        createDefaultVipLevel("青铜", 1,
                BigDecimal.valueOf(500), BigDecimal.valueOf(300),
                BigDecimal.valueOf(1.2), BigDecimal.valueOf(0.95));

        createDefaultVipLevel("白银", 2,
                BigDecimal.valueOf(2000), BigDecimal.valueOf(1000),
                BigDecimal.valueOf(1.5), BigDecimal.valueOf(0.9));

        createDefaultVipLevel("黄金", 3,
                BigDecimal.valueOf(5000), BigDecimal.valueOf(3000),
                BigDecimal.valueOf(2.0), BigDecimal.valueOf(0.85));

        createDefaultVipLevel("铂金", 4,
                BigDecimal.valueOf(10000), BigDecimal.valueOf(5000),
                BigDecimal.valueOf(3.0), BigDecimal.valueOf(0.8));

        createDefaultVipLevel("钻石", 5,
                BigDecimal.valueOf(20000), BigDecimal.valueOf(10000),
                BigDecimal.valueOf(5.0), BigDecimal.valueOf(0.7));
    }

    /**
     * 创建默认VIP等级
     */
    private void createDefaultVipLevel(String name, Integer level,
                                      BigDecimal minTotalConsumption,
                                      BigDecimal minTotalRecharge,
                                      BigDecimal overdraftMultiplier,
                                      BigDecimal interestDiscount) {
        VipLevel vipLevel = new VipLevel(name, level, minTotalConsumption, minTotalRecharge);
        vipLevel.setOverdraftMultiplier(overdraftMultiplier);
        vipLevel.setInterestDiscount(interestDiscount);
        vipLevel.setStatus(VipLevel.RuleStatus.ACTIVE);
        vipLevel.setPriority(level);
        vipLevelRepository.save(vipLevel);
    }

    /**
     * 将实体转换为DTO
     */
    private VipLevelDTO convertToDTO(VipLevel vipLevel) {
        VipLevelDTO dto = new VipLevelDTO();
        dto.setId(vipLevel.getId());
        dto.setName(vipLevel.getName());
        dto.setLevel(vipLevel.getLevel());
        dto.setMinTotalConsumption(vipLevel.getMinTotalConsumption());
        dto.setMinTotalRecharge(vipLevel.getMinTotalRecharge());
        dto.setOverdraftMultiplier(vipLevel.getOverdraftMultiplierValue());
        dto.setInterestDiscount(vipLevel.getInterestDiscountValue());
        dto.setStatus(vipLevel.getStatus().name());
        dto.setPriority(vipLevel.getPriority());
        dto.setCreateTime(vipLevel.getCreateTime());
        dto.setUpdateTime(vipLevel.getUpdateTime());
        return dto;
    }
}
